﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace com.hyrentals.common.image
{
    public class ImageProcessor
    {
        #region 正方型裁剪并缩放
        /// <summary>
        /// 正方型裁剪
        /// 以图片中心为轴心，截取正方型，然后等比缩放
        /// 用于头像处理
        /// </summary>
        /// <param name="filesInfo"></param>
        /// <param name="side"></param>
        /// <param name="quality"></param>
        /// <returns></returns>
        public static byte[] CutForSquare(byte[] filesInfo, int side, int quality)
        {
            return CutForCustom(filesInfo, side, side, quality);
        }
        #endregion


        /// <summary>
        /// 填满
        /// </summary>
        /// <param name="filesInfo"></param>
        /// <param name="dstWidth"></param>
        /// <param name="dstHeight"></param>
        /// <param name="quality"></param>
        /// <returns></returns>
        public static byte[] FillForCustom(byte[] filesInfo, int dstWidth, int dstHeight, int quality)
        {
            MemoryStream ms = new MemoryStream(filesInfo);
            //从文件获取原始图片，并使用流中嵌入的颜色管理信息
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //模版的宽高比例
            double templateRate = (double)dstWidth / dstHeight;
            //原图片的宽高比例
            double initRate = (double)initImage.Width / initImage.Height;

            if (templateRate == initRate)
            {
                MemoryStream resultStream = ZoomByRation2Memory(initImage, dstWidth, dstHeight, quality);
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
            else
            {
                //裁剪对象
                System.Drawing.Image pickedImage = null;
                System.Drawing.Graphics pickedG = null;
                //定位
                Rectangle fromR = new Rectangle(0, 0, initImage.Width, initImage.Height);//原图裁剪定位
                Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位

                //高为标准进行填东西
                if (templateRate > initRate)
                {
                    //裁剪对象实例化
                    pickedImage = new System.Drawing.Bitmap((int)Math.Floor(initImage.Height * templateRate), initImage.Height);
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    //裁剪目标定位
                    toR.X = (int)Math.Floor((initImage.Height * templateRate - initImage.Width) / 2);
                    toR.Y = 0;
                    toR.Width = initImage.Width;
                    toR.Height = initImage.Height;
                }
                //宽为标准进行裁剪
                else
                {
                    pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)Math.Floor(initImage.Width / templateRate));
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    toR.X = 0;
                    toR.Y = (int)Math.Floor((initImage.Width / templateRate - initImage.Height) / 2);
                    toR.Width = initImage.Width;
                    toR.Height = initImage.Height;
                }

                //设置质量
                pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //裁剪
                pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
                MemoryStream resultMemory = ZoomByRation2Memory(pickedImage, dstWidth, dstHeight, quality);
                pickedG.Dispose();

                return resultMemory.GetBuffer();
            }
        }

        /// <summary>
        /// 指定长宽比
        /// 按模板比例最大范围的裁剪图片
        /// </summary>
        /// <param name="filesInfo"></param>
        /// <param name="dstWidth"></param>
        /// <param name="dstHeight"></param>
        /// <param name="quality"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        public static byte[] FillMaxCustom(byte[] filesInfo, int dstWidth, int dstHeight, int quality, out double ratio)
        {
            MemoryStream ms = new MemoryStream(filesInfo);
            //从文件获取原始图片，并使用流中嵌入的颜色管理信息
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //模版的宽高比例
            double templateRate = (double)dstWidth / dstHeight;
            //原图片的宽高比例
            double initRate = (double)initImage.Width / initImage.Height;

            if (templateRate == initRate)
            {
                ratio = (double)initImage.Width / dstWidth;
                return filesInfo;
            }
            else
            {
                //裁剪对象
                System.Drawing.Image pickedImage = null;
                System.Drawing.Graphics pickedG = null;
                //定位
                Rectangle fromR = new Rectangle(0, 0, initImage.Width, initImage.Height);//原图裁剪定位
                Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位

                //高为标准进行填东西
                if (templateRate > initRate)
                {
                    //裁剪对象实例化
                    pickedImage = new System.Drawing.Bitmap((int)Math.Floor(initImage.Height * templateRate), initImage.Height);
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    //裁剪目标定位
                    toR.X = (int)Math.Floor((initImage.Height * templateRate - initImage.Width) / 2);
                    toR.Y = 0;
                    toR.Width = initImage.Width;
                    toR.Height = initImage.Height;
                }
                //宽为标准进行裁剪
                else
                {
                    pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)Math.Floor(initImage.Width / templateRate));
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    toR.X = 0;
                    toR.Y = (int)Math.Floor((initImage.Width / templateRate - initImage.Height) / 2);
                    toR.Width = initImage.Width;
                    toR.Height = initImage.Height;
                }

                //设置质量
                pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //裁剪
                pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
                ratio = (double)pickedImage.Width / dstWidth;
                MemoryStream resultStream = ConvertImage2Memory(pickedImage, quality);

                pickedG.Dispose();
                return resultStream.GetBuffer();
            }
        }

        #region 固定模版裁剪并缩放

        public static byte[] CutByChoice(byte[] inputInfos, int x1, int x2, int y1, int y2, int quality)
        {
            MemoryStream ms = new MemoryStream(inputInfos);
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //裁剪对象实例化
            System.Drawing.Image pickedImage = new System.Drawing.Bitmap(x2 - x1, y2 - y1);
            System.Drawing.Graphics pickedG = System.Drawing.Graphics.FromImage(pickedImage);

            Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
            Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位
            //裁剪源定位
            fromR.X = x1;
            fromR.Y = y1;
            fromR.Width = pickedImage.Width;
            fromR.Height = pickedImage.Height;

            //裁剪目标定位
            toR.X = 0;
            toR.Y = 0;
            toR.Width = pickedImage.Width;
            toR.Height = pickedImage.Height;

            pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //裁剪
            pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
            MemoryStream resultStream = ConvertImage2Memory(pickedImage, quality);
            pickedG.Dispose();
            initImage.Dispose();
            return resultStream.GetBuffer();
        }
        /// <summary>
        /// 指定长宽裁剪
        /// 按模版比例最大范围的裁剪图片并缩放至模版尺寸
        /// </summary>
        /// <param name="inputInfos"></param>
        /// <param name="maxWidth"></param>
        /// <param name="maxHeight"></param>
        /// <param name="quality"></param>
        /// <returns></returns>
        public static byte[] CutForCustom(byte[] inputInfos, int maxWidth, int maxHeight, int quality)
        {
            MemoryStream ms = new MemoryStream(inputInfos);
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //模版的宽高比例
            double templateRate = (double)maxWidth / maxHeight;
            //原图片的宽高比例
            double initRate = (double)initImage.Width / initImage.Height;

            //原图与模版比例相等，直接缩放
            if (templateRate == initRate)
            {
                MemoryStream resultStream = ZoomByRation2Memory(initImage, maxWidth, maxHeight, quality);
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
            else
            {
                //裁剪对象
                System.Drawing.Image pickedImage = null;
                System.Drawing.Graphics pickedG = null;

                //定位
                Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
                Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位

                //宽为标准进行裁剪
                if (templateRate > initRate)
                {
                    //裁剪对象实例化
                    pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)Math.Floor(initImage.Width / templateRate));
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    //裁剪源定位
                    fromR.X = 0;
                    fromR.Y = (int)Math.Floor((initImage.Height - initImage.Width / templateRate) / 2);
                    fromR.Width = initImage.Width;
                    fromR.Height = (int)Math.Floor(initImage.Width / templateRate);

                    //裁剪目标定位
                    toR.X = 0;
                    toR.Y = 0;
                    toR.Width = initImage.Width;
                    toR.Height = (int)Math.Floor(initImage.Width / templateRate);
                }
                //高为标准进行裁剪
                else
                {
                    pickedImage = new System.Drawing.Bitmap((int)Math.Floor(initImage.Height * templateRate), initImage.Height);
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    fromR.X = (int)Math.Floor((initImage.Width - initImage.Height * templateRate) / 2);
                    fromR.Y = 0;
                    fromR.Width = (int)Math.Floor(initImage.Height * templateRate);
                    fromR.Height = initImage.Height;

                    toR.X = 0;
                    toR.Y = 0;
                    toR.Width = (int)Math.Floor(initImage.Height * templateRate);
                    toR.Height = initImage.Height;
                }
                //设置质量
                pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //裁剪
                pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
                MemoryStream resultStream = ZoomByRation2Memory(pickedImage, maxWidth, maxHeight, quality);
                pickedG.Dispose();
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
        }


        /// <summary>
        ///指定长宽比
        ///按模板比例最大范围的裁剪图片
        /// </summary>
        /// <param name="inputInfos"></param>
        /// <param name="dstWidth"></param>
        /// <param name="dstHeight"></param>
        /// <param name="quality"></param>
        /// <returns></returns>
        public static byte[] CutMaxCustom(byte[] inputInfos, int dstWidth, int dstHeight, int quality, out double ratio)
        {
            MemoryStream ms = new MemoryStream(inputInfos);
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //模版的宽高比例
            double templateRate = (double)dstWidth / dstHeight;
            //原图片的宽高比例
            double initRate = (double)initImage.Width / initImage.Height;

            //原图与模版比例相等，直接返回
            if (templateRate == initRate)
            {
                ratio = (double)initImage.Width / dstWidth;
                return inputInfos;
            }
            else
            {
                //裁剪对象
                System.Drawing.Image pickedImage = null;
                System.Drawing.Graphics pickedG = null;

                //定位
                Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
                Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位

                //宽为标准进行裁剪
                if (templateRate > initRate)
                {
                    //裁剪对象实例化
                    pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)Math.Floor(initImage.Width / templateRate));
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    //裁剪源定位
                    fromR.X = 0;
                    fromR.Y = (int)Math.Floor((initImage.Height - initImage.Width / templateRate) / 2);
                    fromR.Width = initImage.Width;
                    fromR.Height = (int)Math.Floor(initImage.Width / templateRate);

                    //裁剪目标定位
                    toR.X = 0;
                    toR.Y = 0;
                    toR.Width = initImage.Width;
                    toR.Height = (int)Math.Floor(initImage.Width / templateRate);
                }
                //高为标准进行裁剪
                else
                {
                    pickedImage = new System.Drawing.Bitmap((int)Math.Floor(initImage.Height * templateRate), initImage.Height);
                    pickedG = System.Drawing.Graphics.FromImage(pickedImage);

                    fromR.X = (int)Math.Floor((initImage.Width - initImage.Height * templateRate) / 2);
                    fromR.Y = 0;
                    fromR.Width = (int)Math.Floor(initImage.Height * templateRate);
                    fromR.Height = initImage.Height;

                    toR.X = 0;
                    toR.Y = 0;
                    toR.Width = (int)Math.Floor(initImage.Height * templateRate);
                    toR.Height = initImage.Height;
                }
                //设置质量
                pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //裁剪
                pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);

                ratio = (double)pickedImage.Width / dstWidth;
                MemoryStream resultStream = ConvertImage2Memory(pickedImage, quality);

                pickedG.Dispose();
                initImage.Dispose();

                return resultStream.GetBuffer();
            }
        }
        #endregion

        #region 自适应裁剪

        public static byte[] AdaptForCustom(byte[] inputInfos, int maxWidth, int maxHeight, int quality)
        {
            MemoryStream ms = new MemoryStream(inputInfos);
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //模版的宽高比例
            double templateRate = (double)maxWidth / maxHeight;
            //原图片的宽高比例
            double initRate = (double)initImage.Width / initImage.Height;

            //原图与模版比例相等，直接缩放
            if (templateRate == initRate)
            {
                MemoryStream resultStream = ZoomByRation2Memory(initImage, maxWidth, maxHeight, quality);
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
            else if (templateRate > initRate)
            {
                MemoryStream resultStream = ZoomByRation2Memory(initImage, (int)Math.Floor(maxHeight * initRate), maxHeight, quality);
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
            else
            {
                MemoryStream resultStream = ZoomByRation2Memory(initImage, maxWidth, (int)Math.Floor(maxWidth / initRate), quality);
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
        }

        #endregion

        #region 水印

        /// <summary>
        /// 画水印Text
        /// </summary>
        /// <param name="initImage"></param>
        /// <param name="watermarkText"></param>
        private static void DrawWaterMarkText(Image initImage, string watermarkText)
        {
            using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(initImage))
            {
                System.Drawing.Font fontWater = new Font("黑体", 10);
                System.Drawing.Brush brushWater = new SolidBrush(Color.Black);
                gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
                gWater.Dispose();
            }
        }

        /// <summary>
        /// 画水印图
        /// </summary>
        /// <param name="initImage"></param>
        /// <param name="watermarkImage"></param>
        private static void DrawWaterMarkImage(Image initImage, string watermarkImage)
        {
            if (File.Exists(watermarkImage))
            {
                //获取水印图片
                using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
                {
                    //水印绘制条件：原始图片宽高均大于或等于水印图片
                    if (initImage.Width >= wrImage.Width && initImage.Height >= wrImage.Height)
                    {
                        Graphics gWater = Graphics.FromImage(initImage);

                        //透明属性
                        ImageAttributes imgAttributes = new ImageAttributes();
                        ColorMap colorMap = new ColorMap();
                        colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                        colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
                        ColorMap[] remapTable = { colorMap };
                        imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                        float[][] colorMatrixElements = {
                                   new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5
                                   new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                };

                        ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
                        imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                        gWater.DrawImage(wrImage, new Rectangle(initImage.Width - wrImage.Width, initImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);
                        gWater.Dispose();
                    }
                    else
                    {
                        throw new Exception("watermark Image is too big to mark。");
                    }
                    wrImage.Dispose();
                }
            }
            else
            {
                throw new FileNotFoundException("watermarkImage:" + watermarkImage);
            }
        }

        /// <summary>
        /// 加图片水印 - 参考自Discuz.Net
        /// </summary>
        /// <param name="imgInfo>图片信息</param>
        /// <param name="watermarkFilename">水印文件名</param>
        /// <param name="watermarkStatus">图片水印位置, 0=不使用 1=左上 2=中上 3=右上 4=左中 ... 9=右下</param>
        /// <param name="quality">//是否是高质量图片 取值范围0--100</param>
        /// <param name="watermarkTransparency">//图片水印透明度 取值范围1--10 (10为不透明)</param>
        public static byte[] AddImageSignPic(byte[] imgInfo, string watermarkFilename, int watermarkStatus, int quality, int watermarkTransparency)
        {
            MemoryStream resultMs = new MemoryStream();
            try
            {
                using (MemoryStream imgMs = new MemoryStream(imgInfo))
                {
                    using (Image img = Image.FromStream(imgMs, true))
                    {
                        using (Graphics g = Graphics.FromImage(img))
                        {
                            //设置高质量插值法
                            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                            //设置高质量,低速度呈现平滑程度
                            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                            using (Image watermark = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, watermarkFilename)))
                            {
                                //if (img.Height < 200 || img.Width < 300)
                                //    return imgInfo;

                                //if (watermark.Height > img.Height || watermark.Width > img.Width)
                                //    return imgInfo;

                                using (ImageAttributes imageAttributes = new ImageAttributes())
                                {
                                    ColorMap colorMap = new ColorMap();

                                    colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                                    colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
                                    ColorMap[] remapTable = { colorMap };

                                    imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                                    float transparency = 0.5F;
                                    if (watermarkTransparency >= 1 && watermarkTransparency <= 10)
                                        transparency = (watermarkTransparency / 10.0F);


                                    float[][] colorMatrixElements = {
                                                new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  0.0f,  0.0f,  transparency, 0.0f},
                                                new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                            };

                                    ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

                                    imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);


                                    #region 打水印
                                    //int xpos = 0;
                                    //int ypos = 0;

                                    //switch (watermarkStatus)
                                    //{
                                    //    case 1:
                                    //        xpos = (int)(img.Width * (float).01);
                                    //        ypos = (int)(img.Height * (float).01);
                                    //        break;
                                    //    case 2:
                                    //        xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                                    //        ypos = (int)(img.Height * (float).01);
                                    //        break;
                                    //    case 3:
                                    //        xpos = (int)((img.Width * (float).99) - (watermark.Width));
                                    //        ypos = (int)(img.Height * (float).01);
                                    //        break;
                                    //    case 4:
                                    //        xpos = (int)(img.Width * (float).01);
                                    //        ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                                    //        break;
                                    //    case 5:
                                    //        xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                                    //        ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                                    //        break;
                                    //    case 6:
                                    //        xpos = (int)((img.Width * (float).99) - (watermark.Width));
                                    //        ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                                    //        break;
                                    //    case 7:
                                    //        xpos = (int)(img.Width * (float).01);
                                    //        ypos = (int)((img.Height * (float).99) - watermark.Height);
                                    //        break;
                                    //    case 8:
                                    //        xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                                    //        ypos = (int)((img.Height * (float).99) - watermark.Height);
                                    //        break;
                                    //    case 9:
                                    //        xpos = (int)((img.Width * (float).99) - (watermark.Width));
                                    //        ypos = (int)((img.Height * (float).99) - watermark.Height);
                                    //        break;
                                    //}

                                    //g.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);

                                    Random r = new Random();
                                    int waterMarkWidth = watermark.Width,
                                        waterMarkHeight = watermark.Height,
                                        imgWidth = img.Width,
                                        imgHeight = img.Height,
                                        waterMarkBoxWidth = (int)(waterMarkWidth * 2),
                                        waterMarkBoxHeight = (int)(waterMarkHeight * 2),
                                        waterMarkMargin = 10,
                                        waterMarkOuterBoxWidth = waterMarkBoxWidth + 2 * waterMarkMargin,
                                        waterMarkOuterBoxHeight = waterMarkBoxHeight + 2 * waterMarkMargin,
                                        waterMarkHorizontalNumber = (int)Math.Ceiling((double)imgWidth / waterMarkOuterBoxWidth),
                                        waterMarkVerticalNumber = (int)Math.Ceiling((double)imgHeight / waterMarkOuterBoxHeight),
                                        xpos = 0,
                                        ypos = 0;

                                    bool hEnough = true;
                                    bool vEnough = true;
                                    if (waterMarkHorizontalNumber == 1)
                                    {
                                        hEnough = false;
                                    }
                                    if (waterMarkVerticalNumber == 1)
                                    {
                                        vEnough = false;
                                    }
                                    for (int h = 0; h < waterMarkHorizontalNumber; ++h)
                                    {
                                        for (int v = 0; v < waterMarkVerticalNumber; ++v)
                                        {
                                            if (hEnough)
                                                xpos = h * waterMarkOuterBoxWidth + waterMarkMargin + r.Next(0, waterMarkBoxWidth - waterMarkWidth);
                                            else
                                                xpos = r.Next(0, imgWidth / 2);

                                            if (vEnough)
                                                ypos = v * waterMarkOuterBoxHeight + waterMarkMargin + r.Next(0, waterMarkBoxHeight - waterMarkHeight);
                                            else
                                                ypos = r.Next(0, imgHeight / 2);
                                            if (xpos < imgWidth && ypos < imgHeight)
                                            {
                                                g.DrawImage(watermark, new Rectangle(xpos, ypos, waterMarkWidth, waterMarkHeight), 0, 0, waterMarkWidth, waterMarkHeight, GraphicsUnit.Pixel, imageAttributes);
                                            }
                                        }
                                    }


                                    #endregion

                                    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                                    ImageCodecInfo ici = null;
                                    foreach (ImageCodecInfo codec in codecs)
                                    {
                                        if (codec.MimeType.IndexOf("jpeg") > -1)
                                            ici = codec;
                                    }
                                    EncoderParameters encoderParams = new EncoderParameters();
                                    long[] qualityParam = new long[1];
                                    if (quality < 0 || quality > 100)
                                        quality = 80;

                                    qualityParam[0] = quality;

                                    EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
                                    encoderParams.Param[0] = encoderParam;


                                    if (ici != null)
                                        img.Save(resultMs, ici, encoderParams);
                                    else
                                        img.Save(resultMs, ImageFormat.Jpeg);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception /*ex*/)
            {
                return imgInfo;
            }
            return resultMs.GetBuffer();

        }

        /// <summary>
        /// 增加图片文字水印 - 参考自Discuz.Net
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="watermarkText">水印文字</param>
        /// <param name="watermarkStatus">图片水印位置</param>
        public static void AddImageSignText(Image img, string filename, string watermarkText, int watermarkStatus, int quality, string fontname, int fontsize)
        {
            Graphics g = Graphics.FromImage(img);
            Font drawFont = new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Pixel);
            SizeF crSize;
            crSize = g.MeasureString(watermarkText, drawFont);

            float xpos = 0;
            float ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (float)img.Width * (float).01;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 2:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = (float)img.Height * (float).01;
                    break;
                case 3:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 4:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 5:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 6:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 7:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 8:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 9:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
            }

            g.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + 1, ypos + 1);
            g.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos);

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType.IndexOf("jpeg") > -1)
                    ici = codec;
            }
            EncoderParameters encoderParams = new EncoderParameters();
            long[] qualityParam = new long[1];
            if (quality < 0 || quality > 100)
                quality = 80;

            qualityParam[0] = quality;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
            encoderParams.Param[0] = encoderParam;

            if (ici != null)
                img.Save(filename, ici, encoderParams);
            else
                img.Save(filename);

            g.Dispose();
            img.Dispose();
        }

        #endregion

        /// <summary>
        ///  图片等比缩放
        /// </summary>
        /// <param name="inputInfos"></param>
        /// <param name="targetWidth"></param>
        /// <param name="targetHeight"></param>
        /// <param name="watermarkText"></param>
        /// <param name="watermarkImage"></param>
        /// <returns></returns>
        public static byte[] ZoomAuto(byte[] inputInfos, double targetWidth, double targetHeight, string watermarkText, string watermarkImage)
        {
            MemoryStream ms = new MemoryStream(inputInfos);
            //原始图片（获取原始图片创建对象，并使用流中嵌入的颜色管理信息）
            System.Drawing.Image initImage = System.Drawing.Image.FromStream(ms, true);

            //原图宽高均小于模版，不作处理，直接保存
            if (initImage.Width <= targetWidth && initImage.Height <= targetHeight)
            {
                //文字水印
                if (!string.IsNullOrEmpty(watermarkText))
                {
                    DrawWaterMarkText(initImage, watermarkText);
                }

                //透明图片水印
                if (!string.IsNullOrEmpty(watermarkImage))
                {
                    DrawWaterMarkImage(initImage, watermarkImage);
                }

                MemoryStream resultStream = new MemoryStream();
                //保存
                initImage.Save(resultStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                return resultStream.GetBuffer();
            }
            else
            {
                //缩略图宽、高计算
                double newWidth = initImage.Width;
                double newHeight = initImage.Height;

                //宽大于高或宽等于高（横图或正方）
                if (initImage.Width > initImage.Height || initImage.Width == initImage.Height)
                {
                    //如果宽大于模版
                    if (initImage.Width > targetWidth)
                    {
                        //宽按模版，高按比例缩放
                        newWidth = targetWidth;
                        newHeight = initImage.Height * (targetWidth / initImage.Width);
                    }
                }
                //高大于宽（竖图）
                else
                {
                    //如果高大于模版
                    if (initImage.Height > targetHeight)
                    {
                        //高按模版，宽按比例缩放
                        newHeight = targetHeight;
                        newWidth = initImage.Width * (targetHeight / initImage.Height);
                    }
                }

                //生成新图
                //新建一个bmp图片
                System.Drawing.Image newImage = new System.Drawing.Bitmap((int)newWidth, (int)newHeight);
                //新建一个画板
                System.Drawing.Graphics newG = System.Drawing.Graphics.FromImage(newImage);

                //设置质量
                newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //置背景色
                newG.Clear(Color.White);
                //画图
                newG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, newImage.Width, newImage.Height), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);

                //文字水印
                if (watermarkText != "")
                {
                    DrawWaterMarkText(newImage, watermarkText);
                }

                //透明图片水印
                if (watermarkImage != "")
                {
                    if (File.Exists(watermarkImage))
                    {
                        DrawWaterMarkImage(newImage, watermarkImage);
                    }
                }
                MemoryStream resultStream = new MemoryStream();
                //保存缩略图
                newImage.Save(resultStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                //释放资源
                newG.Dispose();
                newImage.Dispose();
                initImage.Dispose();
                return resultStream.GetBuffer();
            }
        }

        private static Image ZoomByRation2Image(System.Drawing.Image pickedImage, int maxWidth, int maxHeight, int quality)
        {
            //按模版大小生成最终图片
            System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight);
            System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
            templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            templateG.Clear(Color.White);
            templateG.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel);

            //释放资源
            templateG.Dispose();
            return templateImage;
        }
        private static MemoryStream ConvertImage2Memory(Image templateImage, int quality)
        {
            //关键质量控制
            //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
            ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo i in icis)
            {
                if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
                {
                    ici = i;
                }
            }
            EncoderParameters ep = new EncoderParameters(1);
            ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);

            MemoryStream resultMemory = new MemoryStream();
            //保存缩略图
            templateImage.Save(resultMemory, ici, ep);
            templateImage.Dispose();

            return resultMemory;
        }
        private static MemoryStream ZoomByRation2Memory(System.Drawing.Image pickedImage, int maxWidth, int maxHeight, int quality)
        {
            Image templateImage = ZoomByRation2Image(pickedImage, maxWidth, maxHeight, quality);
            //DrawWaterMarkText(templateImage, "dahuoshuo.com");
            MemoryStream ms = ConvertImage2Memory(templateImage, quality);
            pickedImage.Dispose();
            return ms;
        }

        #region 其它
        /// <summary>
        /// 判断文件类型是否为WEB格式图片
        /// (注：JPG,GIF,BMP,PNG)
        /// </summary>
        /// <param name="contentType">HttpPostedFile.ContentType</param>
        /// <returns></returns>
        public static bool IsWebImage(string contentType)
        {
            if (contentType == "image/pjpeg" || contentType == "image/jpeg" || contentType == "image/gif" || contentType == "image/bmp" || contentType == "image/png")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        public static void SaveOriginalImage(Bitmap bitmap, string distationPath, string format)
        {
            switch (format.ToLower())
            {
                case ".bmp":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Bmp);
                    break;
                case ".emf":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Emf);
                    break;
                case ".gif":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Gif);
                    break;
                case ".ico":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Icon);
                    break;
                case ".jpg":
                case ".jpeg":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    break;
                case ".png":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Png);
                    break;
                case ".tif":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Tiff);
                    break;
                case ".wmf":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Wmf);
                    break;
                default: // use default format
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    break;
            }
        }

        /// <summary>
        /// SaveImage
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="distationPath"></param>
        /// <param name="format"></param>
        public static void SaveImage(Bitmap bitmap, string distationPath, string format, long level = 90L)
        {
            EncoderParameters encoderParameters = new EncoderParameters(1);
            encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, level);

            switch (format.ToLower())
            {
                case ".bmp":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Bmp);
                    break;
                case ".emf":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Emf);
                    break;
                case ".gif":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Gif);
                    break;
                case ".ico":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Icon);
                    break;
                case ".jpg":
                case ".jpeg":
                    bitmap.Save(distationPath, GetEncoder(System.Drawing.Imaging.ImageFormat.Jpeg), encoderParameters);
                    break;
                case ".png":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Png);
                    break;
                case ".tif":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Tiff);
                    break;
                case ".wmf":
                    bitmap.Save(distationPath, System.Drawing.Imaging.ImageFormat.Wmf);
                    break;
                default: throw new Exception("无法转换此格式！");
            }
        }

        public static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
    }//end class
}
